<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import axiosInstance from '../utils/axios';
import { initializeTranslationGroups, addTranslationGroup, triggerTranslation } from '../utils/translationService';

// 路由器，用于页面跳转
const router = useRouter();

// 上传图片相关状态
const uploadedImages = ref<Array<{
  id: number;
  url: string;
  isProcessing: boolean;
  error: string | null;
  prompts: Array<{
    id: number;
    text: string; // 英文提示词
    textCn: string; // 中文提示词
    isSelected: boolean;
    isTranslating: boolean; // 是否正在翻译
  }>;
}>>([]);

const isUploading = ref(false);
const uploadError = ref<string | null>(null);
const nextImageId = ref(1);
const nextPromptId = ref(1);

// 处理图片上传
function handleImageUpload(event: Event) {
  const input = event.target as HTMLInputElement;
  if (!input.files || input.files.length === 0) return;
  
  isUploading.value = true;
  uploadError.value = null;
  
  // 处理多个文件
  Array.from(input.files).forEach(file => {
    if (!file.type.startsWith('image/')) {
      uploadError.value = '请上传图片文件';
      return;
    }
    
    // 读取图片文件
    const reader = new FileReader();
    reader.onload = async (e) => {
      const imageId = nextImageId.value++;
      const base64Data = e.target?.result as string;
      
      // 添加到上传图片列表
      uploadedImages.value.push({
        id: imageId,
        url: base64Data,
        isProcessing: true,
        error: null,
        prompts: []
      });
      
      try {
        // 调用 submitDescribe API
        console.log('正在发送图片数据到服务器...');
        const payload = { base64: base64Data, notifyHook: "", state: "" };
        const response = await axiosInstance.post('/mj/submit/describe', payload);
        console.log('上传成功!', response);
        
        // 获取返回的任务ID
        const responseData = response as any;
        const taskId = responseData.result;
        if (!taskId) {
          throw new Error('未获取到任务ID');
        }
        
        // 等待任务完成并获取提示词
        await checkTaskStatus(taskId, imageId);
      } catch (error: any) {
        console.error('上传或处理图片时出错:', error);
        
        let errorMessage = '处理图片失败，请重试';
        
        // 检查是否是网络错误
        if (error.message && error.message.includes('Network Error')) {
          errorMessage = '网络错误：无法连接到服务器，请检查网络连接或服务器是否运行';
          console.error('CORS或网络错误:', error);
        } else if (error.response) {
          // 服务器返回了错误状态码
          errorMessage = `服务器错误 (${error.response.status}): ${error.response.data?.message || '未知错误'}`;
        }
        
        const imageIndex = uploadedImages.value.findIndex(img => img.id === imageId);
        if (imageIndex !== -1) {
          uploadedImages.value[imageIndex].isProcessing = false;
          uploadedImages.value[imageIndex].error = errorMessage;
        }
        
        if (!uploadError.value) {
          uploadError.value = errorMessage;
        }
      } finally {
        // 在此不设置全局isUploading为false，让每个图片独立完成
      }
    };
    
    reader.onerror = (event) => {
      console.error('读取文件失败:', event);
      uploadError.value = '图片上传失败: 无法读取文件';
      isUploading.value = false;
    };
    
    reader.readAsDataURL(file);
  });
  
  // 清空input，允许重复上传相同文件
  input.value = '';
  
  // 设置一个超时，确保最终将isUploading设置为false
  setTimeout(() => {
    isUploading.value = false;
  }, 3000);
}

// 检查任务状态并获取提示词
async function checkTaskStatus(taskId: string, imageId: number) {
  // 添加开始时间和超时时间设置
  const startTime = Date.now();
  const timeoutDuration = 60000; // 60秒超时
  
  // 递归函数，用于轮询任务状态
  const pollTaskStatus = async () => {
    try {
      console.log(`正在检查任务状态: ${taskId}`);
      const taskResponse = await axiosInstance.post('/mj/task/list-by-condition', { 'ids': [taskId] });
      console.log('任务状态数据:', taskResponse);
      
      const taskResponseData = taskResponse as any;
      
      // 确保返回数据格式正确
      if (!taskResponseData || !Array.isArray(taskResponseData) || taskResponseData.length === 0) {
        throw new Error('未获取到任务数据');
      }
      
      console.log('taskResponseData', taskResponseData);
      
      const taskData = taskResponseData[0];
      
      if (!taskData) {
        throw new Error('未找到任务数据');
      }
      
      // 检查任务状态
      if (taskData.prompt === "Unknown error") {
        throw new Error('上传失败: ' + (taskData.message || '未知错误'));
      } else if (taskData.status === 'SUCCESS') {
        // 处理成功获取的提示词
        processPrompts(taskData, imageId);
        return true; // 成功完成
      } else if (taskData.status === "NOT_START" || taskData.status === 'SUBMITTED') {
        // 检查是否超时
        const currentTime = Date.now();
        if (currentTime - startTime > timeoutDuration) {
          throw new Error('任务处理超时，请稍后查看结果');
        }
        
        // 任务仍在处理中，等待一段时间后再次检查
        console.log(`任务 ${taskId} 仍在处理中，稍后再次检查 (已等待 ${Math.round((currentTime - startTime)/1000)} 秒)`);
        // 使用 setTimeout 并返回 Promise 以便正确处理异步
        return new Promise(resolve => {
          setTimeout(() => {
            resolve(pollTaskStatus());
          }, 5000); // 每2秒检查一次
        });
      } else {
        throw new Error(`任务状态异常: ${taskData.status} - ${taskData.message || ''}`);
      }
    } catch (error: any) {
      console.error('检查任务状态时出错:', error);
      
      let errorMessage = '处理图片失败，请重试';
      
      // 检查是否超时
      if (Date.now() - startTime > timeoutDuration) {
        errorMessage = '任务处理超时，请稍后查看结果';
      } else if (error.message && error.message.includes('Network Error')) {
        errorMessage = '网络错误：无法连接到服务器';
      } else if (error.response) {
        errorMessage = `服务器错误 (${error.response.status}): ${error.response.data?.message || error.message || '未知错误'}`;
      } else if (error.message) {
        errorMessage = error.message;
      }
      
      const imageIndex = uploadedImages.value.findIndex(img => img.id === imageId);
      if (imageIndex !== -1) {
        uploadedImages.value[imageIndex].isProcessing = false;
        uploadedImages.value[imageIndex].error = errorMessage;
      }
      
      isUploading.value = false;
      throw error; // 向上抛出错误以便调用者处理
    }
  };
  
  try {
    // 开始轮询
    await pollTaskStatus();
  } catch (error) {
    console.error('轮询任务状态失败:', error);
    // 错误已在内部处理，这里不需要额外处理
  }
}

// 处理获取到的提示词
function processPrompts(taskData: any, imageId: number) {
  const imageIndex = uploadedImages.value.findIndex(img => img.id === imageId);
  if (imageIndex === -1) return;
  
  try {
    // 提取和处理提示词
    let promptText = taskData.prompt || '';
    
    // 处理 MJ 风格的提示词，按编号分割
    let promptTexts = promptText
      .replaceAll("1️⃣ ", '')
      .replaceAll("2️⃣ ", '')
      .replaceAll("3️⃣ ", '')
      .replaceAll("4️⃣ ", '')
      .split('\n\n');
      
    // 过滤掉空字符串
    promptTexts = promptTexts.filter((text: string) => text.trim() !== '');
    
    // 限制最多4个提示词
    const limitedPrompts = promptTexts.slice(0, 4);
    
    // 生成提示词对象
    const prompts: Array<{
      id: number;
      text: string;
      textCn: string;
      isSelected: boolean;
      isTranslating: boolean;
    }> = [];
    
    for (const text of limitedPrompts) {
      prompts.push({
        id: nextPromptId.value++,
        text: text.trim(), // 英文提示词
        textCn: '', // 中文提示词，初始为空，将通过翻译服务填充
        isSelected: false,
        isTranslating: true
      });
    }
    
    // 更新图片状态和提示词
    uploadedImages.value[imageIndex].isProcessing = false;
    uploadedImages.value[imageIndex].prompts = prompts;
    
    // 更新图片URL（如果服务器返回了处理后的图片）
    if (taskData.imageUrl) {
      uploadedImages.value[imageIndex].url = taskData.imageUrl;
    }
    
    // 等待Vue渲染完成后，再设置翻译组
    setTimeout(() => {
      console.log(`图片 #${imageId} 的提示词渲染完成，开始设置翻译组`);
      
      // 为每个提示词设置翻译组，使用递增延迟确保按顺序处理
      prompts.forEach((prompt, index) => {
        setTimeout(() => {
          setupTranslationForPrompt(imageId, prompt.id);
        }, 100 * index); // 使用递增延迟，确保每个提示词有足够时间完成设置
      });
    }, 500); // 给Vue渲染提供足够的时间
    
  } catch (error) {
    console.error('处理提示词时出错:', error);
    uploadedImages.value[imageIndex].isProcessing = false;
    uploadedImages.value[imageIndex].error = '解析提示词失败';
  } finally {
    isUploading.value = false;
  }
}

// 为提示词设置翻译组
function setupTranslationForPrompt(imageId: number, promptId: number) {
  const imageIndex = uploadedImages.value.findIndex(img => img.id === imageId);
  if (imageIndex === -1) return;
  
  const promptIndex = uploadedImages.value[imageIndex].prompts.findIndex(p => p.id === promptId);
  if (promptIndex === -1) return;
  
  // 创建选择器
  const sourceSelector = `.prompt-text-en-${imageId}-${promptId}`;
  const targetSelector = `.prompt-text-cn-${imageId}-${promptId}`;
  
  // 添加翻译组
  addTranslationGroup({
    sourceField: 'english',
    targetField: 'chinese',
    sourceSelector,
    targetSelector,
    index: promptId, // 使用promptId作为索引
    twoWay: true
  });
  
  // 标记翻译完成
  uploadedImages.value[imageIndex].prompts[promptIndex].isTranslating = false;
  
  // 延迟一段时间后触发翻译，确保DOM元素已经渲染并包含内容
  setTimeout(() => {
    // 再次检查DOM元素是否存在
    const sourceElement = document.querySelector(sourceSelector);
    const targetElement = document.querySelector(targetSelector);
    
    if (sourceElement && targetElement) {
      console.log(`设置翻译触发延迟: imageId=${imageId}, promptId=${promptId}`);
      // 使用递增延迟，避免所有请求同时发送
      setTimeout(() => {
        console.log(`触发翻译: imageId=${imageId}, promptId=${promptId}`);
        // 传递0作为延迟参数，表示立即添加到队列，不需要等待用户输入完成
        triggerTranslation(promptId, false, 0);
      }, 300 + (promptId * 150)); // 根据promptId添加递增延迟
    } else {
      console.warn(`未找到翻译元素: ${sourceSelector} 或 ${targetSelector}`);
    }
  }, 500); // 给DOM渲染一些时间
}

// 删除上传的图片
function removeImage(imageId: number) {
  const index = uploadedImages.value.findIndex(img => img.id === imageId);
  if (index !== -1) {
    uploadedImages.value.splice(index, 1);
  }
}

// 直接执行提示词
async function executePrompt(imageId: number, promptId: number) {
  const imageIndex = uploadedImages.value.findIndex(img => img.id === imageId);
  if (imageIndex === -1) return;
  
  const promptIndex = uploadedImages.value[imageIndex].prompts.findIndex(p => p.id === promptId);
  if (promptIndex === -1) return;
  
  const prompt = uploadedImages.value[imageIndex].prompts[promptIndex];
  const promptText = prompt.text;
  
  // 标记为已选择
  prompt.isSelected = true;
  
  try {
    // 调用API执行提示词生成图片
    console.log('执行提示词:', promptText);
    alert(`正在执行提示词: ${promptText}`);
    
    // 这里可以添加实际的API调用代码
    // 例如：await generateImages({ prompt: promptText, type: TaskType.NORMAL });
    
  } catch (error) {
    console.error('执行提示词出错:', error);
    prompt.isSelected = false; // 重置选择状态
    alert(`执行提示词失败: ${error instanceof Error ? error.message : '未知错误'}`);
  }
}

// 微调提示词（跳转到Uploadview页面）
function adjustPrompt(imageId: number, promptId: number) {
  const imageIndex = uploadedImages.value.findIndex(img => img.id === imageId);
  if (imageIndex === -1) return;
  
  const promptIndex = uploadedImages.value[imageIndex].prompts.findIndex(p => p.id === promptId);
  if (promptIndex === -1) return;
  
  const promptText = uploadedImages.value[imageIndex].prompts[promptIndex].text;
  const imageUrl = uploadedImages.value[imageIndex].url;
  
  // 确保提示词和图片URL存在
  if (!promptText.trim()) {
    alert('提示词内容为空，无法微调');
    return;
  }
  
  // 跳转到Uploadview页面，并传递提示词和图片
  router.push({
    path: '/upload',
    query: {
      prompt: promptText,
      image: imageUrl
    }
  });
}

// 清空所有图片
function clearAllImages() {
  uploadedImages.value = [];
  nextImageId.value = 1;
  nextPromptId.value = 1;
}

// 重试处理图片
async function retryImageProcessing(imageId: number) {
  const imageIndex = uploadedImages.value.findIndex(img => img.id === imageId);
  if (imageIndex === -1) return;
  
  const image = uploadedImages.value[imageIndex];
  
  // 清除错误状态并标记为处理中
  image.error = null;
  image.isProcessing = true;
  
  try {
    // 再次调用API处理图片
    console.log(`重试处理图片 #${imageId}`);
    const payload = { base64: image.url, notifyHook: "", state: "" };
    
    const response = await axiosInstance.post('/mj/submit/describe', payload);
    console.log('重试上传成功!', response);
    
    // 获取返回的任务ID
    const responseData = response as any;
    const taskId = responseData.result;
    if (!taskId) {
      throw new Error('未获取到任务ID');
    }
    
    // 等待任务完成并获取提示词
    await checkTaskStatus(taskId, imageId);
  } catch (error: any) {
    console.error('重试处理图片时出错:', error);
    
    let errorMessage = '处理图片失败，请重试';
    
    if (error.message && error.message.includes('Network Error')) {
      errorMessage = '网络错误：无法连接到服务器，请检查网络连接';
    } else if (error.response) {
      errorMessage = `服务器错误 (${error.response.status}): ${error.response.data?.message || '未知错误'}`;
    } else if (error.message) {
      errorMessage = error.message;
    }
    
    image.isProcessing = false;
    image.error = errorMessage;
  }
}

// 检查API连接
async function checkApiConnection() {
  uploadError.value = "正在检查服务器连接...";
  
  try {
    // 尝试进行一个简单的请求来检查连接
    const response = await axiosInstance.get('health-check');
    console.log('API连接检查成功:', response);
    uploadError.value = "服务器连接正常，可以继续上传图片";
    
    // 3秒后清除提示
    setTimeout(() => {
      if (uploadError.value === "服务器连接正常，可以继续上传图片") {
        uploadError.value = null;
      }
    }, 3000);
    
  } catch (error: any) {
    console.error('API连接检查失败:', error);
    
    // 根据错误类型提供更详细的信息
    if (error.message && error.message.includes('Network Error')) {
      uploadError.value = "网络错误：无法连接到服务器。请确保服务器正在运行且网络连接正常。";
    } else if (error.response) {
      uploadError.value = `服务器返回错误 (${error.response.status}): API可能工作正常，但健康检查端点不存在。`;
    } else {
      uploadError.value = `检查连接失败: ${error.message || '未知错误'}`;
    }
  }
}

// 组件挂载时的操作
onMounted(() => {
  // 初始化翻译服务
  initializeTranslationGroups();
  
  // 监听DOM变化，确保新添加的元素能够正确触发翻译
  const observer = new MutationObserver((mutations) => {
    // 添加节流，避免频繁处理DOM变化
    if (mutations.some(m => m.type === 'childList' && m.addedNodes.length > 0)) {
      // 延迟处理，确保DOM已完全渲染
      setTimeout(() => {
        // 检查是否有新的提示词元素被添加
        const promptElements = document.querySelectorAll('[class^="prompt-text-en-"]');
        if (promptElements.length > 0) {
          console.log(`检测到DOM变化，找到 ${promptElements.length} 个提示词元素`);
          
          // 创建一个映射表，记录已处理的提示词
          const processed = new Set();
          
          // 遍历所有上传的图片和提示词，确保翻译组已设置
          uploadedImages.value.forEach((image) => {
            image.prompts.forEach((prompt) => {
              // 避免重复处理
              const key = `${image.id}-${prompt.id}`;
              if (processed.has(key)) return;
              processed.add(key);
              
              // 检查元素是否存在
              const sourceSelector = `.prompt-text-en-${image.id}-${prompt.id}`;
              const sourceElement = document.querySelector(sourceSelector);
              
              if (sourceElement && !prompt.isTranslating) {
                // 获取实际文本内容
                const sourceText = sourceElement.textContent || '';
                if (sourceText.trim()) {
                  // 为避免冲突，设置延迟
                  const delay = 1000 + (Math.random() * 1000); // 1-2秒随机延迟
                  setTimeout(() => {
                    console.log(`MutationObserver延迟触发翻译: imageId=${image.id}, promptId=${prompt.id}`);
                    // 使用0延迟参数，确保立即触发翻译而不是等待输入完成
                    triggerTranslation(prompt.id, false, 0);
                  }, delay);
                }
              }
            });
          });
        }
      }, 800); // 给DOM渲染充足的时间
    }
  });
  
  // 开始观察DOM变化
  observer.observe(document.body, { childList: true, subtree: true });
});
</script>

<template>
  <div class="image-to-prompt-container">
    <!-- <h2 class="page-title">图生文</h2> -->
    
    <div class="upload-controls">
      <label for="image-upload" class="upload-button" :class="{'disabled': isUploading}">
        <span class="upload-icon">+</span>
        <span class="upload-text">{{ isUploading ? '正在处理...' : '上传图片' }}</span>
      </label>
      <input 
        id="image-upload" 
        type="file" 
        accept="image/*" 
        multiple
        class="upload-input" 
        @change="handleImageUpload"
        :disabled="isUploading"
      />
      
      <button @click="clearAllImages" class="clear-button" v-if="uploadedImages.length > 0" :disabled="isUploading">
        清空所有图片
      </button>
    </div>
    
    <div v-if="uploadError" class="upload-error">
      <p>{{ uploadError }}</p>
      <div class="error-actions">
        <button @click="uploadError = null" class="btn-secondary">关闭</button>
        <button @click="checkApiConnection" class="retry-btn">检查连接</button>
      </div>
    </div>
    
    <!-- 图片列表，修改为两列布局 -->
    <div class="images-container-grid" v-if="uploadedImages.length > 0">
      <div v-for="image in uploadedImages" :key="image.id" class="image-card">
        <div class="image-header">
          <h3 class="image-title">图片 #{{ image.id }}</h3>
          <button @click="removeImage(image.id)" class="remove-image-btn" title="删除图片" :disabled="image.isProcessing">
            ✕
          </button>
        </div>
        
        <div class="image-content">
          <div class="image-preview">
            <img :src="image.url" alt="上传的图片" />
          </div>
          
          <div class="prompts-container">
            <div v-if="image.isProcessing" class="processing-indicator">
              <div class="loading-spinner"></div>
              <p>正在通过AI生成提示词...</p>
              <p class="processing-note">可能需要几秒钟时间，请耐心等待</p>
            </div>
            
            <div v-else-if="image.error" class="prompt-error">
              <p>{{ image.error }}</p>
              <button @click="retryImageProcessing(image.id)" class="retry-btn">重试</button>
            </div>
            
            <div v-else-if="image.prompts.length === 0" class="no-prompts">
              <p>未能生成提示词，请重新上传图片</p>
            </div>
            
            <!-- 提示词列表 -->
            <div v-else class="prompts-list">
              <div v-for="prompt in image.prompts" :key="prompt.id" class="prompt-item" :class="{ 'selected': prompt.isSelected }">
                <div class="prompt-content">
                  <!-- 添加按钮容器在右上角 -->
                  <div class="prompt-action-dots">
                    <button @click="executePrompt(image.id, prompt.id)" class="dot-btn execute-dot" :disabled="prompt.isSelected" title="执行"></button>
                    <button @click="adjustPrompt(image.id, prompt.id)" class="dot-btn adjust-dot" title="微调"></button>
                  </div>
                  
                  <div class="prompt-text-container">
                    <!-- 英文提示词 -->
                    <div 
                      :class="`prompt-text-en prompt-text-en-${image.id}-${prompt.id}`" 
                      contenteditable="true"
                    >{{ prompt.text }}</div>
                    
                    <!-- 中文提示词 -->
                    <div 
                      :class="`prompt-text-cn prompt-text-cn-${image.id}-${prompt.id}`" 
                      contenteditable="true"
                    >{{ prompt.isTranslating ? '正在翻译...' : prompt.textCn }}</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <div v-else-if="!isUploading && !uploadError" class="empty-state">
      <div class="empty-icon">🖼️</div>
      <p class="empty-text">上传图片以获取AI生成的提示词</p>
    </div>
  </div>
</template>

<style scoped>
.image-to-prompt-container {
  padding: 1rem 0;
  max-width: 100%;
  margin: 0 auto;
}

/* 修改为两列网格布局 */
.images-container-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
  width: 100%;
}

.image-card {
  background-color: var(--bg-secondary);
  border-radius: var(--border-radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
  width: 100%;
  height: fit-content;
}

.image-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}

.image-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 1rem;
  border-bottom: 1px solid var(--border-color);
}

.image-title {
  margin: 0;
  font-size: 1rem;
  color: var(--text-primary);
}

.remove-image-btn {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background-color: var(--bg-tertiary);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  cursor: pointer;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.remove-image-btn:hover {
  background-color: #ff6b6b;
  color: white;
}

.image-content {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.image-preview {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: var(--bg-tertiary);
  width: 100%;
  padding: 1rem 0;
}

.image-preview img {
  max-width: 90%;
  max-height: 180px;
  object-fit: contain;
  border-radius: var(--border-radius-md);
}

.prompts-container {
  width: 100%;
  overflow-y: auto;
}

.processing-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  color: var(--text-secondary);
}

.loading-spinner {
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid var(--border-color);
  border-top-color: var(--primary-color);
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 0.75rem;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.prompt-error, .no-prompts {
  color: #ff6b6b;
  text-align: center;
  padding: 1rem;
}

.prompts-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: 100%;
  padding: 0.75rem;
}

.prompt-item {
  background-color: var(--bg-primary);
  border-radius: var(--border-radius-md);
  transition: background-color var(--transition-fast);
  font-size: 0.85rem;
  position: relative; /* 为绝对定位的小圆点按钮提供参考 */
  overflow: visible; /* 允许小圆点超出容器边界 */
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border-color);
}

.prompt-item.selected {
  background-color: rgba(var(--primary-color-rgb), 0.05);
  border-left: 3px solid var(--primary-color);
}

.prompt-content {
  position: relative;
  padding: 0.5rem;
}

/* 小圆点按钮样式 */
.prompt-action-dots {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  display: flex;
  gap: 0.4rem;
  z-index: 5;
}

.dot-btn {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  transition: transform 0.2s, opacity 0.2s;
  padding: 0;
}

.dot-btn:hover {
  transform: scale(1.2);
}

.dot-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.execute-dot {
  background-color: #4CAF50; /* 绿色 */
}

.adjust-dot {
  background-color: #FFC107; /* 黄色 */
}

.prompt-text-container {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: 100%;
  padding-right: 2rem; /* 为小圆点按钮留出空间 */
}

.prompt-text-en, .prompt-text-cn {
  padding: 0.5rem;
  border-radius: var(--border-radius-sm);
  min-height: 1.5rem;
  line-height: 1.4;
  font-size: 0.75rem; /* 减小字体大小 */
  white-space: pre-wrap; /* 保持换行和空格 */
  word-break: break-word; /* 确保长单词能够断行 */
  overflow-wrap: break-word; /* 确保能够包装长单词 */
  max-height: 200px; /* 限制最大高度 */
  overflow-y: auto; /* 添加垂直滚动条 */
}

.prompt-text-en {
  background-color: var(--bg-tertiary);
  color: var(--text-secondary);
}

.prompt-text-cn {
  background-color: var(--bg-secondary);
  color: var(--text-primary);
  font-weight: 500;
}

.upload-controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.upload-button, .clear-button {
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  background-color: var(--primary-color);
  color: white;
  border-radius: var(--border-radius-md);
  cursor: pointer;
  font-weight: 500;
  transition: background-color var(--transition-fast);
}

.upload-input {
  display: none;
}

.clear-button:hover {
  background-color: #ff6b6b;
  color: white;
}

.upload-error {
  text-align: center;
  color: #ff6b6b;
  margin-bottom: 1.5rem;
  padding: 1rem;
  background-color: rgba(255, 107, 107, 0.1);
  border-radius: var(--border-radius-md);
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem 2rem;
  background-color: var(--bg-secondary);
  border-radius: var(--border-radius-lg);
  color: var(--text-tertiary);
}

.empty-icon {
  font-size: 3rem;
  margin-bottom: 1rem;
}

.empty-text {
  font-size: 1.1rem;
}

.upload-button.disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.processing-note {
  font-size: 0.8rem;
  color: var(--text-tertiary);
  margin-top: 0.5rem;
}

.retry-btn {
  margin-top: 0.75rem;
  padding: 0.4rem 1rem;
  background-color: var(--primary-color);
  color: white;
  border: none;
  border-radius: var(--border-radius-sm);
  cursor: pointer;
  font-size: 0.85rem;
  transition: background-color var(--transition-fast);
}

.retry-btn:hover {
  background-color: var(--primary-color-dark);
}

.error-actions {
  display: flex;
  justify-content: center;
  gap: 1rem;
  margin-top: 1rem;
}

.btn-secondary {
  padding: 0.4rem 1rem;
  background-color: var(--bg-tertiary);
  color: var(--text-primary);
  border: none;
  border-radius: var(--border-radius-sm);
  cursor: pointer;
  font-size: 0.9rem;
  transition: background-color var(--transition-fast);
}

.btn-secondary:hover {
  background-color: var(--border-color);
}

/* 响应式调整 */
@media (max-width: 1200px) {
  .images-container-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 900px) {
  .images-container-grid {
    grid-template-columns: 1fr;
  }
}
</style> 